package org.lmj.chatroom.service;

import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.RejectedExecutionHandlers;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;


//不使用implements，使用extend简化开发
//netty应用了多种设计模式，来简化的我们代码的开发
public class WebChatServerInitialize extends ChannelInitializer<SocketChannel> {

    /**
     * 业务线程池线程数
     */
    private static int eventExecutorGroupThreads = 0;

    /**
     * 业务线程池队列长度
     */
    private static int eventExecutorGroupQueues = 0;

    static {
        eventExecutorGroupThreads = Integer.getInteger("websocket.executor.threads", 0);
        if(eventExecutorGroupThreads == 0) {
            eventExecutorGroupThreads = Runtime.getRuntime().availableProcessors();
        }

        eventExecutorGroupQueues = Integer.getInteger("websocket.executor.queues", 0);
        if(eventExecutorGroupQueues == 0) {
            eventExecutorGroupQueues = 512;
        }
    }

    /**
     * 业务线程组
     */
    private static final EventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(
            eventExecutorGroupThreads, new ThreadFactory() {
        private AtomicInteger threadIndex = new AtomicInteger(0);
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "WebSocketRequestHandlerThread_" + this.threadIndex.incrementAndGet());
        }
    }, eventExecutorGroupQueues, RejectedExecutionHandlers.reject());


    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        //是否是websocket请求
        //服务器切换频道将http升级成websocket
        //将0101转http
        //指明工序，谁来做
        //获得管道--要流经多少工序
        //将请求和应答边界吗为http消息
        ChannelPipeline pipeline= socketChannel.pipeline();

        /**
         * 流经管道需要做四道工序
         */

        // WebSocket协议本身是基于HTTP协议的，所以要使用HTTP解编码器
        pipeline.addLast(new HttpServerCodec());
        // 以块的方式来写的处理器
        pipeline.addLast(new ChunkedWriteHandler());
        // Netty是基于分段请求的，HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
        pipeline.addLast(new HttpObjectAggregator(64*1024));
        // 文本消息处理器
        pipeline.addLast( new TextWebSocketFrameHandler());
        //pipeline.addLast(eventExecutorGroup, new TextWebSocketFrameHandler());


       /* pipeline.addLast(new HttpServerCodec())  //请求响应编码节码为http
                .addLast(new HttpObjectAggregator(64*1024)) //信息汇集公司，聚合器 //整成字节后再次封装 //缓冲区//1024这样写会白屏，缓冲区太小
                .addLast(new ChunkedWriteHandler())  //http就发送聊天界面----成块的写处理
                .addLast(new HttpRequestHandler("/chat"))   //chat标识http，否则是http，，，这就是（ChunkedWriteHandler的）现已到工序

                //入队，出队。公聊私聊就要做自己的协议，发图片也要发自己的协议，加标志位决定是公聊私聊
                .addLast(new WebSocketServerProtocolHandler("/chat"))  //是chat就认为是websocket，就用这个类来处理好
                .addLast(new TextWebSocketFrameHandler());
        //初始化通道*/
    }
//public class WebChatServerInitialize extends ChannelInitializer { 不能这样写，且import java.nio.channels.SocketChannel;
//initChannel(Channel channel)里面要用initChannel(SocketChannel socketChannel) 导报为import io.netty.channel.socket.SocketChannel;

}
